查看原文
其他

编写代码的「八荣八耻」(上篇)

编程一生 编程一生 2019-04-09

产品命名:以简单有趣为荣,以冗长难记为耻。

静儿从19年元旦以来,新创建的4个产品:heimdal、carter、hydra、stark。分别对应漫威里的:海姆达尔(Heimdallr是彩虹桥的守护神,我们项目用的是heimdal 是个一个地名,与Heimdallr音译相同)、特工卡特、九头蛇、钢铁侠。

这样做的好处:

1>激发团队热情:

项目开发的时候,自己在打造一个「钢铁侠」要比打造一个「XX支付系统」、「XX管理系统」更激动人心,有木有?

2>精品意识:

自己做的每一个产品,将来都是可以做开源、可以对外宣传、让业界来学习的,这种产品从一开始就要定义一个可对外宣传用的名字。

3>命名规约需求:

《阿里巴巴Java开发手册》里写到,包名两个点之间仅能有一个自然语义的英语单词。Java编程规约要求开发人员在自己定义的包名前加上唯一的前缀,一般人采用自己公司在互联网的域名。不想让自己的包是由太多点号组成的。一个简练的产品名是个不错的选择。


单个方法:以短小精悍为荣,以冗长费神为耻。

代码尽量短小精悍,提高可读性。

静儿用了两周开发一个包含两个服务的新产品hydra,周四上线了。周五做Code Review的时候,刚开始心里有些许伤感,代码也就几千行。每个类、每个方法看起来都很短小。实际上却耗费了挺多精力。而且静儿确信这个交给其他人做要达到同样的质量要多耗费几倍的时间,但似乎在代码中表现不出来。

但是review结束后,团队里另一个代码也写的挺好同事马上发出感叹:「开发工作量巨大。」知音哪!且不说里面整体架构的优化,静儿的一行代码可能实现了更多的功能。所以描述自己产出的一个思路是尽量将自己实现的功能包括改进点说细说明白。现在没有公司绩效把代码行数作为考核项了吧?

举个实战的栗子🌰:

上面的代码实际实现了一个thrift调用结果自动本地缓存,每次取数据都直接从本地缓存中取。执行效率和本地接口调用是一样的。达到了一个远程thrift调用平均耗时5ms。

@Lazy标签对此类进行懒加载。引用了此jar包,不调用就不会执行,也不消耗内存、CPU等资源。

@Component标签是将类的生命周期管理交给Spring。实现了控制反转。

@EnableAspectJAutoProxy(proxyTargetClass = true)java代理不使用默认JDK动态代理方式。而采用动态字节码生成代理。这样做的原因是这个类实现了runnable接口。使用默认的JDK动态代理时是基于接口的,会转成一个代理对象Proxy,而不是对象本身。

评估对资源、效率的需求,采用单线程来定时执行刷新操作,将结果放到map中。单线程更新不存在更新并发问题,因为允许脏读,所以用效率最高的hashmap即可。


代码维护:以持续重构为荣,以停滞不前为耻。

为什么就算已经很成熟的项目,也要冒着:「没有变更就不会出错。变更上线就有造成事故」的风险,不断的迭代升级,1.0到2.0到3.0?对的,不变更一般来说不会出事故。下面两种场景除外:

1>架构不演进,但是业务量在增长。量级的增长可能会导致系统在某一时间点被打垮。阿里云宕机半小时,按照业界SLA的标准,仍然可能宣称可用性维持在4个9。但是架构问题导致的量级增长一般不是能加机器来解决的。短时间很难恢复。

2>有些问题如使用的基础组件,它本身的BUG会在某一时间点被触发。也有可能因为系统漏洞在某一时刻被攻击。所以美团SRE那边专门有针对业界系统的漏洞的检测和升级流程。但是有时候为了更彻底的解决问题也会需要架构的调整。

以上场景肯定要升级迭代的。而更通常的场景是:如果不升级迭代,而团队不断人员变更,使用场景不断的变化。代码渐渐不能表达原有的意思,新人平时没有对代码做过修改,一改就会出错。

所以宁可持续重构出点小错,在代码review,跑集成测试用例时就发现问题。也不能停滞不前。而作为大多数程序员来说,最基本的素养应该是每过一段时间回头看自己以前写的代码,就应该有太烂了,应该重构了的冲动。不然的话,就该反思自己这段时间的学习成长了。


编程思想:以面向对象为荣,以面向过程为耻。

工作中经常发现有些程序员用面向对象的语言写出了面向过程的方法而自己并没有感觉到。举个栗子🌰:

两方进行通信使用json进行数据传输。接收方将接收到的数据转成了json,然后String XXX = json.getString("xxx")。代码里一堆get完成了功能。

这段代码更好的一个实现方式是将接收的数据结构定义成一个对象,在java里可以使用objectMapper等工具直接将json转成有业务含义的对象。

从json字符串转成json对象不算是一种面向对象的思维方式,而更接近于面向过程的实现。因为功能实现了,阅读代码想知道表达什么意思就费劲了。


总结

抽象比细节活的更长久。 --《程序员修炼之道》


相关阅读

《程序员修炼之道》解读

Elasticsearch的基本概念和指标

程序常用的设计技巧

到底多大才算高并发?

美团分布式服务通信框架及服务治理系统OCTO

学会用数据说话-分布式锁究竟可以多少并发?

大话高可用


作者简介

作者是一个有美国硅谷、日本东京工作经验,十二年坚持一线写代码的程序媛。坚持原创文章。欢迎技术交流!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存